//
// Created by twetec on 25-7-30.
//

#ifndef NETWORK_PROBER_BACKUP_HANDLE_SSH_BACKUP_TASK_H
#define NETWORK_PROBER_BACKUP_HANDLE_SSH_BACKUP_TASK_H

#include <coroutine>
#include <future>

#include <network_prober/database/memory_db_holder.h>

namespace network_prober::backup
{
/**
 * SSH IPv4
 */
class SSHBackupIPv4 : public std::enable_shared_from_this<SSHBackupIPv4>
{
public:
    /**
     *  备份
     */
    void backup();

    /**
     * 观测完毕时回调
     */
    void setOnBackupedCallback(std::function<void(std::string_view)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    SSHBackupIPv4(
        std::string_view interface,
        std::string_view target,
        std::string_view command,
        std::string_view account,
        std::string_view password,
        std::string_view privilegedPassword,
        std::uint32_t port
    );

    ~SSHBackupIPv4();

private:
    std::string m_interface;
    std::string m_target;
    std::string m_command;
    std::string m_account;
    std::string m_password;
    std::string m_privilegedPassword;
    std::uint32_t m_port;
    std::function<void(std::string)> m_onBackupedCallback;
    std::future<void> m_onBackupedCallbackFuture;
};

/**
 *  备份处理
 */
class HandleSSHBackupIPv4Awaiter
{
public:
    HandleSSHBackupIPv4Awaiter(const database::BackupTaskModel& backupTask);

    /**
     * 任务是否需要执行await_suspend()
     * @return false 表示未准备好，需要暂停
     */
    bool await_ready();
    /**
     *  在协程暂停后，执行的方法
     * @param handle 协程promise对象句柄
     */
    void await_suspend(std::coroutine_handle<> handle);
    /**
     *  co_await 输出的值
     *  这里用于返回延迟的时间
     */
    std::string await_resume();

private:
    std::string m_interface;
    std::string m_target;
    std::string m_command;
    std::string m_account;
    std::string m_password;
    std::string m_privilegedPassword;
    std::uint32_t m_port;
    std::coroutine_handle<> m_coroutineHandle;
    std::string m_backupData;
};


/**
 * SSH IPv6
 */
class SSHBackupIPv6 : public std::enable_shared_from_this<SSHBackupIPv6>
{
public:
    /**
     *  观测
     */
    void backup();

    /**
     * 观测完毕时回调
     */
    void setOnBackupedCallback(std::function<void(std::string_view)> callback);

    /**
     * @param interface 网口地址
     * @param target 目标地址
     */
    SSHBackupIPv6(
        std::string_view interface,
        std::string_view target,
        std::string_view command,
        std::string_view account,
        std::string_view password,
        std::string_view privilegedPassword,
        std::uint32_t port
    );
    ~SSHBackupIPv6();

private:
    std::string m_interface;
    std::string m_target;
    std::string m_command;
    std::string m_account;
    std::string m_password;
    std::string m_privilegedPassword;
    std::uint32_t m_port;
    std::function<void(std::string_view)> m_onBackupedCallback;
    std::future<void> m_onBackupedCallbackFuture;
};

/**
 *  观测处理
 */
class HandleSSHBackupIPv6Awaiter
{
public:
    HandleSSHBackupIPv6Awaiter(const database::BackupTaskModel& backupTask);

    /**
     * 任务是否需要执行await_suspend()
     * @return false 表示未准备好，需要暂停
     */
    bool await_ready();
    /**
     *  在协程暂停后，执行的方法
     * @param handle 协程promise对象句柄
     */
    void await_suspend(std::coroutine_handle<> handle);
    /**
     *  co_await 输出的值
     *  这里用于返回延迟的时间
     */
    std::string await_resume();

private:
    std::string m_interface;
    std::string m_target;
    std::string m_command;
    std::string m_account;
    std::string m_password;
    std::string m_privilegedPassword;
    std::uint32_t m_port;
    std::coroutine_handle<> m_coroutineHandle;
    std::string m_backupData;
};
}

#endif //NETWORK_PROBER_BACKUP_HANDLE_SSH_BACKUP_TASK_H

